﻿using System;
using Beaker.OpenCube.Render.Maths;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Beaker.OpenCube.Render.Specs
{
	[TestClass]
	public class PointSpecs
	{
		#region Addition

		[TestMethod]
		public void OperatorAdd_PointVector_Point()
		{
			// arrange
			Point3 p = new Point3( 4, 9, 12 );
			Vector3 v = new Vector3( -3, 1, 5 );

			// act
			Point3 np = p + v;

			// assert
			np.X.Should().Be( 4 + -3 );
			np.Y.Should().Be( 9 + 1 );
			np.Z.Should().Be( 12 + 5 );
		}

		[TestMethod]
		public void InstanceAdd_PointVector_Point()
		{
			// arrange
			Point3 p = new Point3( 4, 9, 12 );
			Vector3 v = new Vector3( -3, 1, 5 );

			// act
			Point3 np = p.Add( v );

			// assert
			np.X.Should().Be( 4 + -3 );
			np.Y.Should().Be( 9 + 1 );
			np.Z.Should().Be( 12 + 5 );
		}

		[TestMethod]
		public void StaticAdd_PointVector_Point()
		{
			// arrange
			Point3 p = new Point3( 4, 9, 12 );
			Vector3 v = new Vector3( -3, 1, 5 );

			// act
			Point3 np = Point3.Add( p, v );

			// assert
			np.X.Should().Be( 4 + -3 );
			np.Y.Should().Be( 9 + 1 );
			np.Z.Should().Be( 12 + 5 );
		}

		#endregion
		#region Subtractions

		[TestMethod]
		public void OperatorSubtract_PointVecctor_Point()
		{
			// arrange
			Point3 p = new Point3( 4, 9, 12 );
			Vector3 v = new Vector3( -3, 1, 5 );

			// act
			Point3 np = p - v;

			// assert
			np.X.Should().Be( 4 - -3 );
			np.Y.Should().Be( 9 - 1 );
			np.Z.Should().Be( 12 - 5 );
		}

		[TestMethod]
		public void InstanceSubtract_PointVecctor_Point()
		{
			// arrange
			Point3 p = new Point3( 4, 9, 12 );
			Vector3 v = new Vector3( -3, 1, 5 );

			// act
			Point3 np = p.Subtract( v );

			// assert
			np.X.Should().Be( 4 - -3 );
			np.Y.Should().Be( 9 - 1 );
			np.Z.Should().Be( 12 - 5 );
		}

		[TestMethod]
		public void StaticSubtract_PointVecctor_Point()
		{
			// arrange
			Point3 p = new Point3( 4, 9, 12 );
			Vector3 v = new Vector3( -3, 1, 5 );

			// act
			Point3 np = Point3.Subtract( p, v );

			// assert
			np.X.Should().Be( 4 - -3 );
			np.Y.Should().Be( 9 - 1 );
			np.Z.Should().Be( 12 - 5 );
		}

		[TestMethod]
		public void OperatorSubtract_PointPoint_Vector()
		{
			// arrange
			Point3 p1 = new Point3(13,27,43);
			Point3 p2 = new Point3(-43,-13,-27); 

			// act
			Vector3 v = p1 - p2;

			// assert
			v.X.Should().Be( 13 - -43 );
			v.Y.Should().Be( 27 - -13 );
			v.Z.Should().Be( 43 - -27 );
		}

		[TestMethod]
		public void InstanceSubtract_PointPoint_Vector()
		{
			// arrange
			Point3 p1 = new Point3( 13, 27, 43 );
			Point3 p2 = new Point3( -43, -13, -27 );

			// act
			Vector3 v = p1.Subtract( p2 );

			// assert
			v.X.Should().Be( 13 - -43 );
			v.Y.Should().Be( 27 - -13 );
			v.Z.Should().Be( 43 - -27 );
		}

		[TestMethod]
		public void StaticSubtract_PointPoint_Vector()
		{
			// arrange
			Point3 p1 = new Point3( 13, 27, 43 );
			Point3 p2 = new Point3( -43, -13, -27 );

			// act
			Vector3 v = Point3.Subtract( p1, p2 );

			// assert
			v.X.Should().Be( 13 - -43 );
			v.Y.Should().Be( 27 - -13 );
			v.Z.Should().Be( 43 - -27 );
		}

		#endregion
	}
}
